﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Configuration;
using _2QWebProxy.App_Code;
using System.Windows.Forms;

namespace _2QWebProxy
{
    public class CClient
    {
        public Socket client;
        public Guid guid;
        public Thread ReceiveThread;
        public bool ReceivedProxyInfo = false;
        public ProxyClient proxyClient;
        public ProxyClient agentProxy;
        public string RequestHeader;

        public CClient(Socket client)
        {
            this.client = client;
            this.guid = Guid.NewGuid();

            this.ReceiveThread = new Thread(new ThreadStart(RedirectPackets));
            this.ReceiveThread.Start();
        }

        private void RedirectPackets()
        {
            //GET http://tuoitre.vn/App_Themes/TTOBlue/TTOBlue.css?Version=2.6 HTTP/1.1\r\n
            //Host: tuoitre.vn\r\n
            //User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0\r\n
            //Accept: text/css,*/*;q=0.1\r\n
            //Accept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\n
            //Proxy-Connection: keep-alive\r\n
            //Referer: http://tuoitre.vn/\r\nCookie: TTOCookie=@keyCookieclientCookie@themehttp://tuoitre.vn/App_Themes/TTOBlue/TTOBlue.css@idtabidtinnoibat; ASP.NET_SessionId=kdfl5y45jzuysh4515i3tfrs\r\n
            //If-Modified-Since: Fri, 16 Mar 2012 09:13:11 GMT\r\n
            //If-None-Match: \"806d572553cd1:0\"\r\n\r\n

            try
            {
                byte[] buffer;
                while (client.Connected)
                {
                    string header = String.Empty;

                    buffer = new byte[65535];
                    int recv = client.Receive(buffer);
                    Array.Resize(ref buffer, recv);
                    header = ASCIIEncoding.ASCII.GetString(buffer);

                    // GET & POST
                    if (header.Length > 4 && (header.Substring(0, 3).ToLower().Equals("get") || header.Substring(0, 4).ToLower().Equals("post")))
                    {
                        string host = Utils.FilterHeader(header, "host");
                        IPAddress[] addresslist = Dns.GetHostAddresses(host);
                        if (GlobalVariables.host == "")
                        {
                            GlobalVariables.host = host.ToString();
                            GlobalVariables.ipAddress = addresslist[0].ToString();
                        }
                         
                        // Apply rule
                        bool flag = true;
                        if (Properties.Settings.Default.isRule)
                            flag = Utils.CheckRules(host, addresslist[0].ToString(), null);

                        // Send request to sever
                        if (flag)
                        {
                            RequestHeader = header;
                            // Appy chain proxy
                            if (Properties.Settings.Default.isChainProxy)
                            {
                                // 114.141.180.72 : 3128
                                agentProxy = new ProxyClient(Properties.Settings.Default.chainProxyIP, Properties.Settings.Default.chainProxyPort, this);
                                agentProxy.SendToServer(buffer);
                            }
                            else
                            {
                                //  Not use chain proxy
                                proxyClient = new ProxyClient(addresslist[0].ToString(), 80, this);
                                proxyClient.SendToServer(buffer);
                            }
                        }
                        else
                        {
                            string str = BuildRequestHeader();
                            buffer = Encoding.GetEncoding("UTF-8").GetBytes(str);
                            this.SendToBrowser(buffer);
                            client.Close();
                            //GlobalVariables.host = "";
                        }
                    }
                    else
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                        //GlobalVariables.host = "";
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        public string BuildRequestHeader()
        {
            string str = "";
            str = "Trang web bị chặn bởi 2QWebProxy";
            str = String.Format("HTTP/1.1 200 OK\r\nCneonction: close\r\nDate: {0}\r\nServer: Microsoft-IIS/6.0\r\nX-Powered-By: ASP.NET\r\nX-AspNet-Version: 2.0.50727\r\nCache-Control: private\r\nContent-Type: text/html; charset=utf-8\r\n{1}\r\n\r\n{2}\r\n\r\n", DateTime.Today.ToLongDateString(), Encoding.Unicode.GetBytes(str).Length,str);
            return str;
        }

        public void SendToBrowser(byte[] packet)
        {
            client.Send(packet);
        }

    }
}
